Spring Security ব্যবহার করে REST API এর জন্য নিরাপত্তা কনফিগারেশন করা খুবই গুরুত্বপূর্ণ, কারণ এটি API এর মাধ্যমে প্রবাহিত ডেটা এবং রিসোর্সকে সুরক্ষিত রাখে। REST API এর জন্য Spring Security কনফিগারেশনের মাধ্যমে আপনি Authentication এবং Authorization নিয়ন্ত্রণ করতে পারেন।
এখানে একটি REST API এর জন্য Spring Security কনফিগারেশন করার ধাপ দেওয়া হলো:
Step 1: Maven Dependency
প্রথমে, আপনার pom.xml ফাইলে Spring Security এবং Spring Boot Web এর নির্ভরতাগুলি যোগ করুন:
<dependencies>
<!-- Spring Boot Starter Web (for REST API) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Security (for Security) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA (for Database) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database for testing purposes (replace with actual DB in production) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Starter Validation (for validating inputs) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
Step 2: Security Configuration for REST API
Spring Security তে REST API-এর জন্য নিরাপত্তা কনফিগার করার জন্য SecurityConfig ক্লাস তৈরি করুন। এখানে আমরা JWT (JSON Web Token) ব্যবহার করে নিরাপত্তা কনফিগার করব।
SecurityConfig ক্লাস:
package com.example.config;
import com.example.security.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors().and() // Enable CORS (Cross-Origin Resource Sharing)
.csrf().disable() // Disable CSRF for stateless REST API
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public API endpoints
.antMatchers("/api/auth/**").permitAll() // Authentication related endpoints
.anyRequest().authenticated() // All other requests require authentication
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); // Add JWT authentication filter
return http.build();
}
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
}
Explanation:
cors(): CORS (Cross-Origin Resource Sharing) সক্রিয় করা হয়েছে, কারণ আপনি যদি API থেকে অন্য ডোমেনের অ্যাপ্লিকেশন অ্যাক্সেস করতে চান তবে CORS প্রয়োজন হবে।csrf().disable(): REST API-তে CSRF (Cross-Site Request Forgery) সুরক্ষা সাধারণত প্রয়োজন হয় না, কারণ এটি স্টেটলেস (stateless) অ্যাপ্লিকেশন। ক্লায়েন্ট প্রতিবার নতুন JWT পাঠাবে, তাই CSRF থেকে নিরাপদ থাকবে।authorizeRequests(): এখানে আপনি API এর বিভিন্ন এন্ডপয়েন্টকে বিভিন্নভাবে অ্যাক্সেস কন্ট্রোল করতে পারেন।/public/**: পাবলিক রিসোর্স যা সকল ব্যবহারকারীর জন্য খোলা।/api/auth/**: লগইন বা রেজিস্ট্রেশন এর মতো অথেনটিকেশন সম্পর্কিত এন্ডপয়েন্ট।anyRequest().authenticated(): অন্যান্য সমস্ত রিকোয়েস্ট শুধুমাত্র অথেনটিকেটেড ইউজারদের জন্য।
addFilterBefore(): এখানে কাস্টম JWT ফিল্টার যোগ করা হয়েছে, যা UsernamePasswordAuthenticationFilter এর আগে রিকোয়েস্টে চলবে। এটি JWT টোকেন যাচাই করবে এবং ইউজারকে অথেনটিকেট করবে।
Step 3: JWT Authentication Filter
JWT টোকেন যাচাই করার জন্য একটি কাস্টম ফিল্টার তৈরি করুন। এই ফিল্টারটি HTTP হেডার থেকে JWT টোকেন পড়ে এবং তার ভিত্তিতে ব্যবহারকারীকে অথেনটিকেট করবে।
JwtAuthenticationFilter ক্লাস:
package com.example.security;
import com.example.util.JwtUtil;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
public JwtAuthenticationFilter(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String token = getJwtFromRequest(request);
if (token != null && jwtUtil.validateToken(token)) {
String username = jwtUtil.getUsernameFromToken(token);
if (username != null) {
// Create authentication token and set it in the security context
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, null, null)
);
}
}
filterChain.doFilter(request, response);
}
private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7); // Remove "Bearer " prefix
}
return null;
}
}
Explanation:
getJwtFromRequest(request): HTTP রিকোয়েস্ট থেকে Authorization হেডার থেকে JWT টোকেন বের করা হয়।jwtUtil.validateToken(token): JWT টোকেন যাচাই করা হয়।SecurityContextHolder.getContext().setAuthentication(): যদি JWT টোকেন বৈধ হয়, তবেSecurityContextএ ব্যবহারকারীর তথ্য সেট করা হয়, যাতে Spring Security পরবর্তী রিকোয়েস্টগুলিতে এটি ব্যবহার করতে পারে।
Step 4: JWT Utility Class
এটি একটি JwtUtil ক্লাস যা JWT টোকেন তৈরি এবং যাচাই করার কাজ করবে।
JwtUtil ক্লাস:
package com.example.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtil {
private final String SECRET_KEY = "mySecretKey";
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10 hours expiration
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public boolean validateToken(String token) {
try {
Claims claims = extractClaims(token);
return !claims.getExpiration().before(new Date());
} catch (Exception e) {
return false;
}
}
public String getUsernameFromToken(String token) {
return extractClaims(token).getSubject();
}
private Claims extractClaims(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
Explanation:
generateToken(username): একটি নতুন JWT টোকেন তৈরি করে।validateToken(token): JWT টোকেনটি বৈধ কিনা তা যাচাই করে।getUsernameFromToken(token): JWT টোকেন থেকে ব্যবহারকারীর নাম বের করে।
Step 5: REST Controller
এখন, আমরা একটি REST Controller তৈরি করব যেখানে ব্যবহারকারী লগইন করবে এবং JWT টোকেন পাবে।
AuthController ক্লাস:
package com.example.controller;
import com.example.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
// Authenticate the user (in a real-world scenario, authenticate with DB)
if ("user".equals(username) && "password123".equals(password)) {
return jwtUtil.generateToken(username); // Generate and return JWT
} else {
throw new RuntimeException("Invalid credentials");
}
}
}
Explanation:
/api/auth/login: এই এন্ডপয়েন্টে ব্যবহারকারী ইউজারনেম এবং পাসওয়ার্ড প্রদান করবে এবং যদি সঠিক হয় তবে JWT টোকেন প্রদান করা হবে।
Conclusion
এটি একটি পূর্ণাঙ্গ উদাহরণ ছিল যেখানে Spring Security এবং JWT ব্যবহার করে REST API এর জন্য নিরাপত্তা কনফিগার করা হয়েছে। এই কনফিগারেশনটি আপনাকে stateless অথেনটিকেশন এবং অথরাইজেশন প্রদান করে, যেখানে JWT টোকেন ব্যবহারকারীদের সেশন ট্র্যাকিং ছাড়াই API রিসোর্সে অ্যাক্সেস দেয়।
Read more